import json
import time
from django.views.generic.base import View
from django.shortcuts import render
from django.db.models import Q
from django.http import JsonResponse
from django.conf import settings
from pure_pagination import Paginator, PageNotAnInteger
from utils.mixin_utils import LoginRequiredMixin
from utils.form_utils import get_form_errors
from utils.JsonDateEncoder import JsonDateEncoder
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from systems.models import Dept, UserProfile
from systems.forms import DeptForm


class ListView(LoginRequiredMixin, View):
    def get(self, request):
        v_search = request.GET.get('search')
        if v_search:
            v_search = v_search.strip()
            v_objs = Dept.objects.filter(Q(name__icontains=v_search) | Q(owner__icontains=v_search) |
                                         Q(phone__icontains=v_search) | Q(email__icontains=v_search),
                                         is_delete=0).order_by('parent_id', 'sort')
        else:
            v_objs = Dept.objects.filter(is_delete=0).order_by('parent_id', 'sort')

        # 分页功能实现
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(v_objs, per_page=settings.PAGE_NUM, request=request)
        p_objs = p.page(page)
        p_start = (int(page) - 1) * settings.PAGE_NUM  # 避免分页后每行数据序号从1开始
        return render(request, 'systems/dept_list.html', {'p_objs': p_objs, 'p_start': p_start, 'p_sum': v_objs.count,
                                                          'h_search': v_search})


class AddView(LoginRequiredMixin, View):
    def get(self, request):
        dept_tree = get_dept_tree2()
        return render(request, 'systems/dept.html', {'h_depts': dept_tree,
                                                     'h_dept_belongs': dept_tree})

    def post(self, request):
        v_form = DeptForm(request.POST)
        if v_form.is_valid():
            new_obj = v_form.save(commit=False)
            new_obj.creator = request.user.username
            new_obj.modifier = request.user.username
            # 数据归属部门不填，则默认为当前创建用户的部门ID
            if new_obj.dept_belong_id is None:
                new_obj.dept_belong_id = request.user.dept_id
            new_obj.save()
            return JsonResponse({'code': '200', 'msg': '新增成功'})
        else:
            return JsonResponse({'code': '444', 'msg': get_form_errors(v_form)})


class DetailView(LoginRequiredMixin, View):
    def get(self, request):
        v_obj = Dept.objects.get(id=request.GET.get('id'))
        return render(request, 'systems/dept.html', {'h_obj': v_obj,
                                                     'h_depts': get_dept_tree2(v_obj.parent_id),
                                                     'h_dept_belongs': get_dept_tree2(v_obj.dept_belong_id)})


class ModifyView(LoginRequiredMixin, View):
    def post(self, request):
        v_obj = Dept.objects.get(id=request.POST.get('id'))
        v_form = DeptForm(request.POST, instance=v_obj)
        if v_form.is_valid():
            old_obj = v_form.save(commit=False)
            old_obj.modifier = request.user.username
            # 数据归属部门不填，则默认为当前创建用户的部门ID
            if old_obj.dept_belong_id is None:
                old_obj.dept_belong_id = request.user.dept_id
            old_obj.save()
            return JsonResponse({'code': '200', 'msg': '修改成功'})
        else:
            return JsonResponse({'code': '444', 'msg': get_form_errors(v_form)})


class DeleteView(LoginRequiredMixin, View):
    def get(self, request, i_id):
        if i_id == 1:
            return JsonResponse({'code': '444', 'msg': '根部门禁止删除'})
        v_users = UserProfile.objects.filter(is_delete=0, dept_id=i_id)
        if bool(v_users):
            return JsonResponse({'code': '444', 'msg': '该部门下已关联用户，禁止删除'})

        v_obj = Dept.objects.get(id=i_id)
        v_obj.delete()
        return JsonResponse({'code': '200', 'msg': '删除成功'})


def get_dept_tree(i_user_dept_id=None):
    """
    获取部门树，只能选子节点
    :return: 返回HTML格式的部门树
    """
    dept_tree = ''
    depts = Dept.objects.filter(is_delete=0, status=1)

    def get_blank(i_num):
        i = 1
        result = ''
        while i <= i_num:
            result += '&nbsp;&nbsp;'
            i = i + 1
        return result

    def get_child(i_dept_id, i_dept_name, i_blank_num, i_selected_dept_id):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for dept1 in depts:
            if dept1.parent is not None and dept1.parent.id == i_dept_id:
                exist_child = True
                child_tree += get_child(dept1.id, dept1.name, i_blank_num + 1, i_selected_dept_id)

        if exist_child:
            return f'<optgroup label="{get_blank(i_blank_num)}{i_dept_name}">{child_tree}</optgroup>'
        else:
            if i_dept_id == i_selected_dept_id:
                return f'<option selected value="{i_dept_id}">{get_blank(i_blank_num - 1)}{i_dept_name}</option>'
            else:
                return f'<option value="{i_dept_id}">{get_blank(i_blank_num - 1)}{i_dept_name}</option>'

    for dept in depts:
        if dept.parent is None:
            if i_user_dept_id is None:
                dept_tree = get_child(dept.id, dept.name, -1, 0)
            else:
                dept_tree = get_child(dept.id, dept.name, -1, int(i_user_dept_id))
            break

    return dept_tree


def get_dept_tree2(i_user_dept_id=None):
    """
    获取部门树，可选父节点
    :return: 返回HTML格式的部门树
    """
    dept_tree = ''
    depts = Dept.objects.filter(is_delete=0, status=1)

    def get_blank(i_num):
        i = 1
        result = ''
        while i <= i_num:
            result += '&nbsp;&nbsp;'
            i = i + 1
        return result

    def get_child(i_dept_id, i_dept_name, i_blank_num, i_selected_dept_id):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for dept1 in depts:
            if dept1.parent is not None and dept1.parent.id == i_dept_id:
                exist_child = True
                child_tree += get_child(dept1.id, dept1.name, i_blank_num + 1, i_selected_dept_id)

        if exist_child:
            if i_dept_id == i_selected_dept_id:
                return f'<option selected value="{i_dept_id}">{get_blank(i_blank_num + 1)}{i_dept_name}</option>{child_tree}'
            else:
                return f'<option value="{i_dept_id}">{get_blank(i_blank_num + 1)}{i_dept_name}</option>{child_tree}'
        else:
            if i_dept_id == i_selected_dept_id:
                return f'<option selected value="{i_dept_id}">{get_blank(i_blank_num + 1)}{i_dept_name}</option>'
            else:
                return f'<option value="{i_dept_id}">{get_blank(i_blank_num + 1)}{i_dept_name}</option>'

    for dept in depts:
        if dept.parent is None:
            if i_user_dept_id is None:
                dept_tree = get_child(dept.id, dept.name, -1, 0)
            else:
                dept_tree = get_child(dept.id, dept.name, -1, int(i_user_dept_id))
            break
    return dept_tree


class ClientListView(APIView):
    """客户端：部门列表"""
    permission_classes = [AllowAny]
    authentication_classes = [JSONWebTokenAuthentication]

    def post(self, request):
        objs = Dept.objects.filter(~Q(parent=None), is_delete=0, status=1) \
            .values('id', 'name').order_by('parent', 'sort')
        json_str = json.dumps(list(objs), cls=JsonDateEncoder, ensure_ascii=False)
        json_data = json.loads(json_str)  # 序列化成json对象
        return Response({'code': '000000', 'msg': '查询成功', 'data': json_data,
                         'retTime': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})